package com.sugon.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.dao.SysMsgDao;
import com.sugon.entity.SysMsgEntity;
import com.sugon.entity.SysUserEntity;
import com.sugon.modules.sys.consts.SysPerms;
import com.sugon.service.SysMsgService;
import com.sugon.service.SysUserRoleService;
import com.sugon.service.SysUserService;
import com.sugon.utils.ProcessInfoEnum;
import com.sugon.utils.ShiroUtils;
import com.sugon.utils.StringUtils;
import com.sugon.utils.SysMsgType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service("sysMsgService")
public class SysMsgServiceImpl implements SysMsgService {

    @Autowired
    private SysMsgDao msgDao;
    @Autowired
    private SysUserRoleService userRoleService;
    @Autowired
    private SysUserService userService;

    /**
     * 列表查询
     *
     * @param dataType 数据类别
     * @param dataId   业务数据ID
     * @param userId   用户ID
     * @return
     */
    @Override
    public List<SysMsgEntity> listAll(String dataType, String dataId, String userId) {
        Map<String, Object> param = new HashMap<>();
        param.put("datatype", dataType);
        param.put("dataid", dataId);
        param.put("userId", userId);
        return msgDao.select(param);
    }

    /**
     * @param msgEntity 系统消息中心表作为整体参数做插入
     * @return
     */
    @Override
    public Integer inSysMsgService(SysMsgEntity msgEntity) {
        msgEntity.setId(RandomUtil.randomString(32));
        msgEntity.setIsRead(0);
        return msgDao.save(msgEntity);
    }

    /**
     * @param msgEntity
     * @return
     */
    @Override
    public Map allMsgData(SysMsgEntity msgEntity) {
        msgEntity.setStartDate(DateUtil.date());
        /**
         * 流程id
         */
        String dataId = msgEntity.getDataId();
        /**
         * 流程类型
         */
        String dataType = msgEntity.getDataType();
        /**
         * 流程是否已经结束(已经结束的话直接传'1'过来就行，没结束的时候不要传值或者传'0'进来)
         */
        String dataFlag = msgEntity.getDataFlag();
        Map<String, Object> mapMsg = new HashMap<>();
        try {
            if (!StringUtils.isNotEmpty(dataId) || !StringUtils.isNotEmpty(dataType)) {
                return (Map) mapMsg.put("msg", "新增的参数不能为空");
            }
            if ("1".equals(dataFlag)) {
                Integer flagMsg = this.delSysMsgService(dataId, dataType, null);
                if (flagMsg > 0) {
                    return (Map) mapMsg.put("msg", "删除成功");
                } else {
                    return (Map) mapMsg.put("msg", "删除失败");
                }
            }
            // TODO 暂时注释掉 一个事情只保留一条信息
//            delSysMsgService(dataId, dataType, msgEntity.getStartDate());
            if ("1".equals(dataFlag)) {
                return (Map) mapMsg.put("msg", "删除失败");
            }
            List<SysMsgEntity> msgOnly = listAll(dataId, dataType, msgEntity.getUserId());
            if (CollectionUtil.isEmpty(msgOnly)) {
                Integer flagMsg = this.inSysMsgService(msgEntity);
                if (flagMsg > 0) {
                    return (Map) mapMsg.put("msg", "新增成功");
                } else {
                    return (Map) mapMsg.put("msg", "新增失败");
                }
            } else {
                Integer flagMsg = this.upSysMsgService(msgEntity);
                if (flagMsg > 0) {
                    return (Map) mapMsg.put("msg", "修改成功");
                } else {
                    return (Map) mapMsg.put("msg", "修改失败");
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return (Map) mapMsg.put("msg", e.getMessage());
        }
    }

    /**
     * @return
     */
    @Override
    public List<Map<String, Object>> queryDept() {
        try {
            List<Map<String, Object>> deptList = msgDao.selectDept();
            return deptList;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    /**
     * @param msgEntity 系统消息中心表作为整体参数做更新
     * @return
     */
    @Override
    public Integer upSysMsgService(SysMsgEntity msgEntity) {
        return msgDao.update(msgEntity);
    }

    /**
     * @param userId
     * @return
     */
    @Override
    public List<Map<String, Object>> seeSysMsgService(String userId) {
        return msgDao.selectSysMsgAllData(userId);

    }

    /**
     * @param data_id   流程表id
     * @param data_type 流程类型
     * @param startDate 开始日期
     * @return
     */
    @Override
    public Integer delSysMsgService(String data_id, String data_type, Date startDate) {
        String startDateStr = null;
        if (startDate != null) {
            startDateStr = DateUtil.formatDateTime(startDate);
        }
        return msgDao.delete(data_id, data_type, startDateStr);
    }

    /**
     * @param type   消息类别
     * @param userId 用户ID
     * @return
     */
    @Override
    public List<Map<String, Object>> querySysMsgService(String type, String userId) {
        return msgDao.querySysMsgDataResource(type, userId);
    }

    /**
     * @param msgEntity
     * @return
     */
    @Override
    public Integer upSysMsgDataService(SysMsgEntity msgEntity) {
        return msgDao.upSysMsgDataResource(msgEntity);
    }

    /**
     * @param approveItemType 提醒事项类别
     * @param ticketId        工单ID
     * @param userId          需要被通知的用户
     */
    @Override
    public void addRemindItem(ProcessInfoEnum approveItemType, String ticketId, String userId) {
        SysMsgEntity sysMsgEntity = new SysMsgEntity();
        sysMsgEntity.setDataId(ticketId);
        sysMsgEntity.setDataUrl(StrUtil.format(approveItemType.getApproveUrl(), ticketId));
        sysMsgEntity.setType(approveItemType.getMsgType());
        sysMsgEntity.setTitle(approveItemType.getDesc());
        sysMsgEntity.setDataType(approveItemType);
        sysMsgEntity.setStartDate(DateUtil.date());
        if (StrUtil.isEmpty(userId)) {
            // 查询审批人员ID列表
            List<Map<String, Object>> deptRoleUserList = userRoleService.queryDeptMenuUserList(ShiroUtils.getWorkshop(), approveItemType.getSysPerms()[0].getMenuId());
            if (CollectionUtil.isNotEmpty(deptRoleUserList)) {
                for (Map<String, Object> deptRoleUser : deptRoleUserList) {
                    sysMsgEntity.setDept(MapUtil.getStr(deptRoleUser, "DEPT_CODE"));
                    sysMsgEntity.setUserId(MapUtil.getStr(deptRoleUser, "USER_ID"));
                    allMsgData(sysMsgEntity);
                }
            }
        } else {
            SysUserEntity userEntity = userService.queryObject(userId);
            if (userEntity != null) {
                sysMsgEntity.setDept(userEntity.getDeptCode());
            }
            sysMsgEntity.setUserId(userId);
            allMsgData(sysMsgEntity);
        }
    }

    /**
     * @param approveItemType 提醒事项类别
     * @param dataId          业务数据ID
     * @param userId          需要被通知的用户
     * @param approveLevel    审批LEVEL
     */
    @Override
    public void addApproveItem(ProcessInfoEnum approveItemType, String dataId, String userId, int approveLevel) {
        SysMsgEntity sysMsgEntity = new SysMsgEntity();
        sysMsgEntity.setDataId(dataId);
        sysMsgEntity.setDataUrl(StrUtil.format(approveItemType.getApproveUrl(), dataId));
        sysMsgEntity.setType(approveItemType.getMsgType());
        sysMsgEntity.setTitle(approveItemType.getDesc());
        sysMsgEntity.setDataType(approveItemType);
        sysMsgEntity.setStartDate(DateUtil.date());
        if (StrUtil.isEmpty(userId)) {
            // 查询审批人员ID列表
            List<Map<String, Object>> deptRoleUserList = userRoleService.queryDeptMenuUserList(ShiroUtils.getWorkshop(), approveItemType.getSysPerms()[approveLevel].getMenuId());
            if (CollectionUtil.isNotEmpty(deptRoleUserList)) {
                for (Map<String, Object> deptRoleUser : deptRoleUserList) {
                    sysMsgEntity.setDept(MapUtil.getStr(deptRoleUser, "DEPT_CODE"));
                    sysMsgEntity.setUserId(MapUtil.getStr(deptRoleUser, "USER_ID"));
                    allMsgData(sysMsgEntity);
                }
            }
        } else {
            SysUserEntity userEntity = userService.queryObject(userId);
            if (userEntity != null) {
                sysMsgEntity.setDept(userEntity.getDeptCode());
            }
            allMsgData(sysMsgEntity);
        }
    }

    /**
     * @param approveItemType 审批事项类别
     * @param sysMsgEntity
     * @param approveLevel    审批层级，某一个审批的第几级审批,从0开始
     */
    @Override
    public void addApproveItem(ProcessInfoEnum approveItemType, SysMsgEntity sysMsgEntity, int approveLevel) {
        // 确保一个业务只保留一条系统消息
        msgDao.deleteByDataId(sysMsgEntity.getDataId());
        // 小于0，则表示所有流程已结束，不需要执行后续生成消息
        if (approveLevel < 0) {
            return;
        }
        sysMsgEntity.setType(SysMsgType.APPROVAL_REMIND);
        sysMsgEntity.setTitle(approveItemType.getDesc());
        sysMsgEntity.setDataType(approveItemType);
        if (StrUtil.isEmpty(sysMsgEntity.getUserId())) {
            // 校验是否已设置权限，如果没则不需要生成消息
            SysPerms[] sysPerms = approveItemType.getSysPerms();
            if (ArrayUtil.isEmpty(sysPerms)) {
                return;
            }
            // 查询审批人员ID列表
            /*
                强化逻辑，特种重要
                当条件分支不一时，验是否已设置权限，如果没则不需要生成消息
                但条件分支一致时，校验实发发哈设计开发哈萨克就
             */
            List<Map<String, Object>> deptRoleUserList = userRoleService.queryDeptMenuUserList(ShiroUtils.getWorkshop(), sysPerms[approveLevel].getMenuId());
            if (CollectionUtil.isNotEmpty(deptRoleUserList)) {
                for (Map<String, Object> deptRoleUser : deptRoleUserList) {
                    sysMsgEntity.setDept(MapUtil.getStr(deptRoleUser, "DEPT_CODE"));
                    sysMsgEntity.setUserId(MapUtil.getStr(deptRoleUser, "USER_ID"));
                    allMsgData(sysMsgEntity);
                }
            }
        } else {
            SysUserEntity userEntity = userService.queryObject(sysMsgEntity.getUserId());
            if (userEntity != null) {
                sysMsgEntity.setDept(userEntity.getDeptCode());
            }
            allMsgData(sysMsgEntity);
        }
    }

    /**
     * @param sparePartRecordId 换件记录ID
     * @param approveLevel      审批级别
     */
    @Override
    public void addMoldReplacePartApproveItem(String sparePartRecordId, int approveLevel) {
        SysMsgEntity msgEntity = new SysMsgEntity();
        msgEntity.setDataId(sparePartRecordId);
        msgEntity.setDataUrl("../module/modulereplacepart.html?Id=" + sparePartRecordId);
        addApproveItem(ProcessInfoEnum.MDE_BJGH, msgEntity, 0);
    }

    /**
     * @param ticketId     设备维护工单ID
     * @param approveLevel 审批级别
     */
    @Override
    public void addDevMaintenancePlanChangeApproveItem(String ticketId, int approveLevel) {
        /*
                强化逻辑，特种重要
                当条件分支不一时，验是否已设置权限，如果没则不需要生成消息
                但条件分支一致时，校验实发发哈设计开发哈萨克就
             */
        SysMsgEntity msgEntity = new SysMsgEntity();
        msgEntity.setDataId(ticketId);
        msgEntity.setDataUrl("../device/devplangc.html?Id=" + ticketId);
        addApproveItem(ProcessInfoEnum.DEV_WHGD, msgEntity, 0);
    }

    /**
     * @param checkPlanId  工装周期性检测计划ID
     * @param approveLevel 审批级别
     */
    @Override
    public void addToolsCheckPlanApproveItem(String checkPlanId, int approveLevel) {
        SysMsgEntity sysMsgEntity = new SysMsgEntity();
        sysMsgEntity.setDataId(checkPlanId);
        /*
                强化逻辑，特种重要
                当条件分支不一时，验是否已设置权限，如果没则不需要生成消息
                但条件分支一致时，校验实发发哈设计开发哈萨克就
             */
        sysMsgEntity.setDataUrl("../tools/toolscheckplan.html?Id=" + checkPlanId);
        addApproveItem(ProcessInfoEnum.TLS_GZZQJCGL, sysMsgEntity, 0);
    }

    /**
     * @param sparePartNeedsPlanId 备件需求计划ID
     * @param approveLevel         审批级别
     */
    @Override
    public void addSparePartNeedsPlanApproveItem(String sparePartNeedsPlanId, int approveLevel) {
        SysMsgEntity sysMsgEntity = new SysMsgEntity();
        sysMsgEntity.setDataId(sparePartNeedsPlanId);
        /*
                强化逻辑，特种重要
                当条件分支不一时，验是否已设置权限，如果没则不需要生成消息
                但条件分支一致时，校验实发发哈设计开发哈萨克就
             */
        sysMsgEntity.setDataUrl("../spare/sparepartrequ.html?Id=" + sparePartNeedsPlanId);
        addApproveItem(ProcessInfoEnum.SPA_BJXQ, sysMsgEntity, 0);
    }

    @Override
    public void addSparePartSafeStockApproveItem(String id, int approveLevel) {


        SysMsgEntity sysMsgEntity = new SysMsgEntity();
        sysMsgEntity.setDataId(id);
        /*
                强化逻辑，特种重要
                当条件分支不一时，验是否已设置权限，如果没则不需要生成消息
                但条件分支一致时，校验实发发哈设计开发哈萨克就
             */
        sysMsgEntity.setDataUrl(StrUtil.format(ProcessInfoEnum.SPA_BJAQKC.getApproveUrl(), id));
        addApproveItem(ProcessInfoEnum.SPA_BJAQKC, sysMsgEntity, 0);
    }

    /**
     * @param moldRepairRecordId 模具维修记录
     * @param approveLevel       审批级别
     */
    @Override
    public void addMoldRepairApproveItem(String moldRepairRecordId, int approveLevel) {
        SysMsgEntity sysMsgEntity = new SysMsgEntity();
        sysMsgEntity.setDataId(moldRepairRecordId);
        sysMsgEntity.setDataUrl("../module/modulerepairrocord.html?Id=" + moldRepairRecordId);
        addApproveItem(ProcessInfoEnum.MOLD_REPAIR_RP, sysMsgEntity, 0);
    }

    /**
     * @param moldMaintenanceRecordId
     * @param approveLevel            审批级别
     */
    @Override
    public void addMoldMaintenanceApproveItem(String moldMaintenanceRecordId, int approveLevel) {
        SysMsgEntity sysMsgEntity = new SysMsgEntity();
        sysMsgEntity.setDataId(moldMaintenanceRecordId);
        sysMsgEntity.setDataUrl("../module/modulePlanWork.html?Id=" + moldMaintenanceRecordId);
        addApproveItem(ProcessInfoEnum.MOLD_MAINTENANCE_RP, sysMsgEntity, 0);
    }

    /**
     * @param sparePartId  备件ID
     * @param approveLevel 审批级别,设置到多层审批时，指定由第几层进行审批,从0开始
     */
    @Override
    public void generateSparePartApproveItemMsg(String sparePartId, int approveLevel) {
        SysMsgEntity msgEntity = new SysMsgEntity();
        msgEntity.setDataId(sparePartId);
        msgEntity.setDataUrl("../spare/sparepart.html?Id=" + sparePartId);
        addApproveItem(ProcessInfoEnum.SPA_BJGL, msgEntity, approveLevel);
    }
}
